package pl.rpr.rozklad;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

class Autobus {
  private String adres;
  private String numer;

  public Autobus() {
    this.adres = new String();
    this.numer = new String();
  }

  public Autobus(String adres, String numer) {
    this.adres = adres;
    this.numer = numer;
  }

  public String getAdres() {
    return adres;
  }

  public void setAdres(String adres) {
    this.adres = new String(adres);
  }

  public String getNumer() {
    return numer;
  }

  public void setNumer(String numer) {
    this.numer = new String(numer);
  }
}

class AutobusyListAdapter extends ArrayAdapter<Autobus> {
  private List<Autobus>  autobusy;
  private List<Autobus>  kopiaZapasowaAut;
  private List<Autobus>  filtrowane;
  private Context        context;
  private AutobusyFilter filter;

  public AutobusyListAdapter(Context context, int textViewResourceId, List<Autobus> autobusy2) {
    super(context, textViewResourceId, autobusy2);
    this.context = context;
    this.autobusy = autobusy2;
    this.kopiaZapasowaAut = new ArrayList<Autobus>(autobusy);
    this.filtrowane = new ArrayList<Autobus>(autobusy);
    this.filter = new AutobusyFilter();
  }

  @Override
  public int getCount() {
    return autobusy.size();
  }

  @Override
  public Autobus getItem(int position) {
    return autobusy.get(position);
  }

  @Override
  public long getItemId(int position) {
    return 0;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    LinearLayout listaLayout;
    String adresAutobusu = autobusy.get(position).getAdres();
    String numerAutobusu = autobusy.get(position).getNumer();

    listaLayout = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.autobusy, parent, false);

    TextView numerTV = (TextView) listaLayout.findViewById(R.id.numerA2);
    numerTV.setText(numerAutobusu);

    TextView adresTV = (TextView) listaLayout.findViewById(R.id.adresA2);
    adresTV.setText(adresAutobusu);

    return listaLayout;
  }

  @Override
  public Filter getFilter() {
    if (filter == null)
      filter = new AutobusyFilter();
    return filter;
  }

  private class AutobusyFilter extends Filter {

    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
      constraint = constraint.toString().toLowerCase();
      FilterResults result = new FilterResults();
      if (constraint != null && constraint.toString().length() > 0) {
        List<Autobus> kopiaFil = new ArrayList<Autobus>();
        List<Autobus> kopiaPrz = new ArrayList<Autobus>();
        synchronized (this) {
          kopiaPrz.addAll(kopiaZapasowaAut);
        }
        for (int i = 0, l = kopiaPrz.size(); i < l; ++i) {
          Autobus a = kopiaPrz.get(i);
          if (a.getNumer().toLowerCase().startsWith(constraint.toString()))
            kopiaFil.add(a);
        }
        result.values = kopiaFil;
        result.count = kopiaFil.size();
      } else {
        synchronized (this) {
          result.values = kopiaZapasowaAut;
          result.count = kopiaZapasowaAut.size();
        }
      }
      return result;
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
      filtrowane = (List<Autobus>) results.values;
      notifyDataSetChanged();
      clear();
      for (int i = 0, l = filtrowane.size(); i < l; ++i)
        add(filtrowane.get(i));
    }

  }
}

class AutobusyTextWatcher implements TextWatcher {
  AutobusyListAdapter adapter;

  public AutobusyTextWatcher(AutobusyListAdapter ad) {
    this.adapter = ad;
  }

  public void onTextChanged(CharSequence s, int start, int before, int count) {
    adapter.getFilter().filter(s);
  }

  public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  }

  public void afterTextChanged(Editable s) {
  }
}

public class Autobusy extends ListActivity implements CONST {
  private AutobusyListAdapter adapter;
  private AutobusyTextWatcher filtrAutobusow;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    new Polaczenie(this).sprawdzPolaczenie();

    String htmlDoParsowania = wczytajStringAutobusow(ADRES_AUTOBUSOW);

    List<Autobus> autobusy = new ArrayList<Autobus>();
    autobusy = parsujAutobusy(htmlDoParsowania);

    adapter = new AutobusyListAdapter(this, R.layout.autobusy, autobusy);

    filtrAutobusow = new AutobusyTextWatcher(adapter);

    EditText search = new EditText(this);
    search.setInputType(3);
    search.addTextChangedListener(filtrAutobusow);
    getListView().addHeaderView(search, null, true);

    getListView().setAdapter(adapter);
  }

  @Override
  protected void onListItemClick(ListView parent, View view, int position, long id) {
    super.onListItemClick(parent, view, position, id);
    Intent intent = new Intent(view.getContext(), KierunkiZAutobusow.class);
    TextView adresTV = (TextView) view.findViewById(R.id.adresA2);
    String adres = adresTV.getText().toString();
    intent.putExtra("adresAutobusu", adres);
    startActivity(intent);
  }

  @Override
  protected void onResume() {
    super.onResume();
    new Polaczenie(this).sprawdzPolaczenie();
  }

  @Override
  protected void onRestart() {
    super.onRestart();
    new Polaczenie(this).sprawdzPolaczenie();
  }

  private String wczytajStringAutobusow(String adresAutobusow) {
    HttpClient klient = new DefaultHttpClient();
    HttpGet zadanie = new HttpGet(adresAutobusow);
    HttpResponse odpowiedz = null;
    String htmlDoParsowania = null;
    InputStream strumienWejsciowy = null;
    BufferedReader czytnik = null;
    StringBuilder stringBuilder = new StringBuilder();
    String linia = null;

    try {
      odpowiedz = klient.execute(zadanie);
      strumienWejsciowy = odpowiedz.getEntity().getContent();
      czytnik = new BufferedReader(new InputStreamReader(strumienWejsciowy, "ISO-8859-2"));
      while ((linia = czytnik.readLine()) != null) {
        stringBuilder.append(linia);
      }
      strumienWejsciowy.close();
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IllegalStateException e) {
      e.printStackTrace();
    } catch (UnsupportedEncodingException e1) {
      e1.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    htmlDoParsowania = stringBuilder.toString();
    return htmlDoParsowania;
  }

  private List<Autobus> parsujAutobusy(String htmlDoParsowania) {
    ArrayList<Autobus> autobusy = new ArrayList<Autobus>();
    Pattern patAutobusow = Pattern.compile(RE_NUMERY);
    Matcher matAutobusow = patAutobusow.matcher(htmlDoParsowania);
    while (matAutobusow.find()) {
      Autobus tmp = new Autobus(matAutobusow.group(1), matAutobusow.group(2));
      autobusy.add(tmp);
    }
    return autobusy;
  }

}
